package com.zy.util;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import java.util.LinkedList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 分页工具类
 *
 * @author gtyan
 * @date 2022-07-04 10:28
 */
@Component
@Slf4j
public class PageUtil {

    /**
     * 分页对象内容copy
     *
     * @param page        分页对象
     * @param targetClass 目标类
     * @return 返回分页对象
     * @author gtyan
     * @date 2022-07-04 10:43
     */
    public static <T, E> Page<T> copy(Page<E> page, Class<T> targetClass) {
        Page<T> pageResult = new Page<>();
        pageResult.setCurrent(page.getCurrent());
        pageResult.setSize(page.getSize());
        pageResult.setTotal(page.getTotal());
        List<E> records = page.getRecords();
        if (ObjectUtils.isNotEmpty(records)) {
            List<T> resultList = copy(records, targetClass);
            pageResult.setRecords(resultList);
        }
        return pageResult;
    }

    /**
     * 集合对象copy
     *
     * @param list        集合对象
     * @param targetClass 目标类
     * @return 返回集合对象
     * @author gtyan
     * @date 2022-07-05 0:00
     */
    public static <T, E> List<T> copy(List<E> list, Class<T> targetClass) {
        List<T> resultList = new LinkedList<>();
        if (ObjectUtils.isEmpty(list)) {
            return resultList;
        }
        list.forEach(o -> {
            try {
                T result = targetClass.newInstance();
                BeanUtils.copyProperties(o, result);
                resultList.add(result);
            } catch (InstantiationException | IllegalAccessException e) {
                log.error("", e);
            }
        });
        return resultList;
    }

    public static <T> Page<T> createPage(Long current, Long size, Long total) {
        current = org.springframework.util.ObjectUtils.isEmpty(current) ? 1L : current;
        size = org.springframework.util.ObjectUtils.isEmpty(size) ? 10L : size;
        total = org.springframework.util.ObjectUtils.isEmpty(total) ? 0L : total;
        return new Page<>(current, size, total);
    }

    /**
     * Page1 范型 Source 向 Page2 范型 Target 的类型转换
     *
     * @param source   待转换的数据
     * @param mapFunc  描述 Page1 Source 类型的一行数据如何转换成 Target 类型。同 Java8 Stream API 中 map() 用法
     * @param <Source> 源数据类型
     * @param <Target> 目标数据类型
     * @return Page2 范型 Target 的实例
     */
    public static <Source, Target> Page<Target> translatePage(Page<Source> source, Function<Source, Target> mapFunc) {
        Page<Target> pageVo = new Page<>();
        pageVo.setSize(source.getSize());
        pageVo.setCurrent(source.getCurrent());
        pageVo.setTotal(source.getTotal());
        if (!org.springframework.util.ObjectUtils.isEmpty(source.getRecords())) {
            List<Target> voRecords = source.getRecords()
                    .stream()
                    .map(mapFunc)
                    .collect(Collectors.toList());

            pageVo.setRecords(voRecords);
        }
        return pageVo;
    }

    public static <T> Page<T> emptyPage(long current, long size) {
        return new Page<>(current, size);
    }
}
